package server.comm;


import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;

import utils.LogHelper;

import messaage.DisconnectMsg;
import messaage.LogoutMsg;
import messaage.Message;
 
public class ConnectionHandler implements Runnable {
 
    private final Socket _socket;
    private final Encoder _encoder;
    private final Tokenizer _tokenizer;
    private final ForumProtocol _protocol;
    private ClientStub _client;
 
    public ConnectionHandler(Socket s, Encoder encoder, Tokenizer tokenizer, ForumProtocol protocol,
    		ClientStub client, PrintWriter pw) {
        _socket = s;
        _encoder = encoder;
        _tokenizer = tokenizer;
        _protocol= protocol;
        _client = client;
    }
 
    public ClientStub getStubClient() {
		return _client;
	}

	public void run() {
        while (!_protocol.shouldClose() && !_socket.isClosed()) {                          
            try {
                if (!_tokenizer.isAlive()){
                    _protocol.connectionTerminated();
                }
                   
                else {
                    String msg = _tokenizer.nextToken();
                    String ans = _protocol.processMessage(msg,_client, this);
                    this.send(ans);
                }
            } catch (IOException e) {
               //_protocol.connectionTerminated();
                break;
            }
        }
        try {
            _socket.close();
        } catch (IOException ignored) {
        }
        try {
    	Message logout = new LogoutMsg(getUsername());
        _protocol.processLogout(logout, _client, this);
        Message end = new DisconnectMsg(_client.getClientName());
        _protocol.processDisconnect(end, _client);
        //do disconnect client if he disconnected brutally
        }
        catch (Exception e) {
        	//no exception supposed to happen
        }
        LogHelper.instance().log("IP " + _client.getClientSocket().getInetAddress() + 
        		" has left the server");
        
    }
	
	public void send(String msg) {
		try {
			if (msg != null) {
	            byte[] buf = _encoder.toBytes(msg);
	            System.out.println("Send: \n"+msg);
	            _socket.getOutputStream().write(buf, 0, buf.length);
	            _socket.getOutputStream().flush();
	        }
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}
	
	public String getUsername() {
		return this._client.getClientName();
	}

}